﻿#include "GUIFESubSysFormSEASubSysDialog.h"
#include "ui_GUIFESubSysFormSEASubSysDialog.h"

#include "FITK_Component/FITKAcousticsModel/FITKAcousticsDiscModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAcousticsSEAModel.h"
#include "FITK_Component/FITKAcousticsModel/FITKAbstractFESubSys.h"
#include "FITK_Component/FITKAcousticsModel/FITKAbstractSEASubSys.h"
#include "FITK_Component/FITKAcousticsModel/FITKSEASubSysGeoProp.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsPhysics.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsSpectraManager.h"
#include "FITK_Component/FITKAcousticsPhysics/FITKAcousticsAbstractSpectra.h"
// Pick
#include "PickDataProvider/GUIPickInfo.h"
#include "PickDataProvider/PickedDataProvider.h"
#include "PickDataProvider/PickedData.h"

#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppSettings.h" 
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"

#include <cmath>

namespace GUI {
    GUIFESubSysFormSEASubSysDialog::GUIFESubSysFormSEASubSysDialog(Core::FITKActionOperator* oper, QWidget* parent /*= nullptr*/) :
        GUIDialogBase(parent),
        _oper(oper),
        _ui(new Ui::GUIFESubSysFormSEASubSysDialog)
    {
        _ui->setupUi(this);
        // 设置对话框关闭时自动删除
        setAttribute(Qt::WA_DeleteOnClose);
        //去掉问号
        Qt::WindowFlags flags = windowFlags();
        flags &= ~Qt::WindowContextHelpButtonHint;
        setWindowFlags(flags);
        //组件输入限定初始化
        _ui->lineEdit_ElemLength->setValidator(new QRegExpValidator(QRegExp("^(\\d+(\\.\\d+)?)$")));
        _ui->lineEdit_ElemLength_2->setValidator(new QRegExpValidator(QRegExp("^(\\d+(\\.\\d+)?)$")));
        _ui->lineEdit_MergeNode->setValidator(new QRegExpValidator(QRegExp("^(\\d+(\\.\\d+)?)$")));
        _ui->lineEdit_ElemNumber->setValidator(new QRegExpValidator(QRegExp("^([1-9]+(\\d+)?)$")));
        _ui->lineEdit_ElemNumber_2->setValidator(new QRegExpValidator(QRegExp("[0-9]+$")));
        //绑定拾取信号
        GraphData::PickedDataProvider* pickProvider = GraphData::PickedDataProvider::getInstance();
        //清除拾取对象所有的连接
        QObject::disconnect(pickProvider, SIGNAL(sig_pickedOver()), nullptr, nullptr);
        if (pickProvider)
            connect(pickProvider, &GraphData::PickedDataProvider::sig_pickedOver, this, &GUIFESubSysFormSEASubSysDialog::pickDataFinished);
        //设置窗口自适应隐藏组件
        this->layout()->setSizeConstraint(QLayout::SetMinAndMaxSize);
    }

    GUIFESubSysFormSEASubSysDialog::~GUIFESubSysFormSEASubSysDialog()
    {
        //释放数据
        if (_ui) {
            delete _ui;
            _ui = nullptr;
        }
    }

    void GUIFESubSysFormSEASubSysDialog::init()
    {
        if (!_oper) return;
        int type = 0;
        if (!_oper->argValue<int>("FESubSysType", type)) return;
        if (type == Acoustics::FITKAbstractFESubSys::FESubSysType::FEStructure)
            this->initStructural();
        else if (type == Acoustics::FITKAbstractFESubSys::FESubSysType::FEAcoustic)
            this->initAcoustic();
    }

    void GUIFESubSysFormSEASubSysDialog::initStructural()
    {
        //拾取类型
        _ui->comboBox_PickType->addItem(tr("SEA Shell"), GUI::GUIPickInfo::PickObjType::POBJSEAShell);
        _ui->comboBox_PickType->addItem(tr("SEA Beam"), GUI::GUIPickInfo::PickObjType::POBJSEABeam);
        _ui->comboBox_PickType->addItem(tr("Face Mesh"), GUI::GUIPickInfo::PickObjType::POBJMeshCell2D);
        _ui->comboBox_PickType->addItem(tr("Beam Mesh"), GUI::GUIPickInfo::PickObjType::POBJMeshCell1D);
        //初始化界面
        _ui->comboBox_PickType->setCurrentIndex(0);
        _ui->tabWidget->tabBar()->hide();
        _ui->tabWidget->setCurrentIndex(0);
        _ui->lineEdit_MergeNode->setText("1e-06");
        //设置单元大小
        _ui->lineEdit_ElemLength->setText("0.00877458");
        _ui->lineEdit_ElemNumber->setText("0");
        _ui->radioButton_Tri->setChecked(true);
        _ui->radioButton_ElemLength->setChecked(true);

        this->initPropComboBox();
    }

    void GUIFESubSysFormSEASubSysDialog::initAcoustic()
    {
        //拾取类型
        _ui->comboBox_PickType->addItem(tr("SEA Acoustic Cavity"), GUI::GUIPickInfo::PickObjType::POBJSEACavity);
        _ui->comboBox_PickType->addItem(tr("Volume Mesh"), GUI::GUIPickInfo::PickObjType::POBJMeshCell3D);
        //初始化界面
        _ui->comboBox_PickType->setCurrentIndex(0);
        _ui->tabWidget->tabBar()->hide();
        _ui->tabWidget->setCurrentIndex(1);
        //设置单元大小
        _ui->lineEdit_ElemLength_2->setText("0.0107187");
        _ui->lineEdit_ElemNumber_2->setText("0");
        _ui->radioButton_ElemLength_2->setChecked(true);

        this->initPropComboBox();
    }

    void GUIFESubSysFormSEASubSysDialog::initPropComboBox()
    {
        //清空数据下拉链表
        _ui->comboBox_DampLoss->clear();
        _ui->comboBox_DampLoss_2->clear();
        //初始化损耗因子下拉列表
        Acoustics::FITKAcousticsPhysics* phyMgr = FITKAPP->getGlobalData()->getPhysicsData<Acoustics::FITKAcousticsPhysics>();
        if (!phyMgr)return;
        //获取频谱管理器
        Acoustics::FITKAcousticsSpectraManager* spectraMgr = phyMgr->getFITKAcousticsSpectraManager();
        if (!spectraMgr)return;
        QList<Acoustics::FITKAcousticsAbstractSpectra*> spectraList = spectraMgr->getSpectraByType(Acoustics::FITKAcousticsAbstractSpectra::AcousticsSpectraType::Damping);
        for (QList<Acoustics::FITKAcousticsAbstractSpectra*>::iterator iter = spectraList.begin(); iter != spectraList.end(); ++iter)
        {
            if (*iter == nullptr)continue;
            _ui->comboBox_DampLoss->addItem((*iter)->getDataObjectName(), (*iter)->getDataObjectID());
            _ui->comboBox_DampLoss_2->addItem((*iter)->getDataObjectName(), (*iter)->getDataObjectID());
        }
    }

    void GUIFESubSysFormSEASubSysDialog::on_pushButton_Cancel_clicked()
    {
        //点击取消按键动作
        this->reject();
    }

    void GUIFESubSysFormSEASubSysDialog::on_pushButton_OK_clicked()
    {
        //获取拾取类型
        GUI::GUIPickInfo::PickObjType pickType = GUI::GUIPickInfo::PickObjType(_ui->comboBox_PickType->currentData().toInt());
        if (pickType == GUI::GUIPickInfo::PickObjType::POBJSEAShell || pickType == GUI::GUIPickInfo::PickObjType::POBJSEABeam || pickType == GUI::GUIPickInfo::PickObjType::POBJSEACavity)
        {
            //设置网格划分的尺寸大小
            double sizeMesh = _ui->lineEdit_ElemLength->text().toDouble();
            int numMesh = _ui->lineEdit_ElemNumber->text().toInt();
            bool isDeleteSEA = _ui->checkBox_DelSEASubSys->checkState() == Qt::CheckState::Checked;
            int dampingLossID = _ui->comboBox_DampLoss->currentData().toInt();
            bool isCoalesceNode = _ui->checkBox_CoalesceNode->checkState() == Qt::CheckState::Checked;
            double mergeNode = _ui->lineEdit_MergeNode->text().toDouble();
            bool isTri = _ui->radioButton_Tri->isChecked();
            if (pickType == GUI::GUIPickInfo::PickObjType::POBJSEACavity)
            {
                sizeMesh = _ui->lineEdit_ElemLength_2->text().toDouble();
                numMesh = _ui->lineEdit_ElemNumber_2->text().toInt();
                isDeleteSEA = _ui->checkBox_DelSEASubSys_2->checkState() == Qt::CheckState::Checked;
                dampingLossID = _ui->comboBox_DampLoss_2->currentData().toInt();
            }
            _oper->setArgs("IsTri", isTri);
            _oper->setArgs("IsCoalesceNode", isCoalesceNode);
            _oper->setArgs("MergeNode", mergeNode);
            _oper->setArgs("MeshSize", sizeMesh);
            _oper->setArgs("MeshNumber", numMesh);
            _oper->setArgs("IsDeleteSEA", isDeleteSEA);
            _oper->setArgs("DampingLossID", dampingLossID);
        }
        if (!_oper)return;
        _oper->setArgs("PickType", (int)pickType);
        this->accept();
    }

    void GUIFESubSysFormSEASubSysDialog::on_radioButton_ElemNumber_toggled(bool checkState)
    {
        if (checkState)
        {
            _ui->lineEdit_ElemLength->setEnabled(false);
            _ui->lineEdit_ElemNumber->setEnabled(true);
        }
    }

    void GUIFESubSysFormSEASubSysDialog::on_radioButton_ElemLength_toggled(bool checkState)
    {
        if (checkState)
        {
            _ui->lineEdit_ElemLength->setEnabled(true);
            _ui->lineEdit_ElemNumber->setEnabled(false);
        }
    }

    void GUIFESubSysFormSEASubSysDialog::on_radioButton_ElemNumber_2_toggled(bool checkState)
    {
        if (checkState)
        {
            _ui->lineEdit_ElemLength_2->setEnabled(false);
            _ui->lineEdit_ElemNumber_2->setEnabled(true);
        }
    }

    void GUIFESubSysFormSEASubSysDialog::on_radioButton_ElemLength_2_toggled(bool checkState)
    {
        if (checkState)
        {
            _ui->lineEdit_ElemLength_2->setEnabled(true);
            _ui->lineEdit_ElemNumber_2->setEnabled(false);
        }
    }

    void GUIFESubSysFormSEASubSysDialog::on_lineEdit_ElemLength_textChanged(QString text)
    {
        double size = text.toDouble();
        if (_subSysObj == nullptr || size < 1e-15) return;
        //阻塞信号触发
        _ui->lineEdit_ElemNumber->blockSignals(true);
        //获取类型
        Acoustics::FITKAbstractSEASubSys::SEASubSysType type = _subSysObj->getSEASubSysType();
        Acoustics::FITKSEASubSysGeoProp* geoProp = _subSysObj->getGeoProp();
        if (!geoProp) return;
        if (type == Acoustics::FITKAbstractSEASubSys::SEASubSysType::SEABeam)
        {
            //获取周长
            double circ = geoProp->getGeoProp(Acoustics::FITKSEASubSysGeoProp::GeoPropType::Circumference);
            int num = circ / size;
            _ui->lineEdit_ElemNumber->setText(QString::number(num));
        }
        else
        {
            //获取面积
            double area = geoProp->getGeoProp(Acoustics::FITKSEASubSysGeoProp::GeoPropType::Area);
            int num = area / (sqrt(3) * size * size / 4);
            _ui->lineEdit_ElemNumber->setText(QString::number(num));
        }
        _ui->lineEdit_ElemNumber->blockSignals(false);
    }

    void GUIFESubSysFormSEASubSysDialog::on_lineEdit_ElemNumber_textChanged(QString text)
    {
        int number = text.toDouble();
        if (_subSysObj == nullptr || number <= 0) return;
        //阻塞信号触发
        _ui->lineEdit_ElemLength->blockSignals(true);
        //获取类型
        Acoustics::FITKAbstractSEASubSys::SEASubSysType type = _subSysObj->getSEASubSysType();
        Acoustics::FITKSEASubSysGeoProp* geoProp = _subSysObj->getGeoProp();
        if (!geoProp) return;
        if (type == Acoustics::FITKAbstractSEASubSys::SEASubSysType::SEABeam)
        {
            //获取周长
            double circ = geoProp->getGeoProp(Acoustics::FITKSEASubSysGeoProp::GeoPropType::Circumference);
            double size = circ / number;
            _ui->lineEdit_ElemLength->setText(QString::number(size));
        }
        else
        {
            //获取面积
            double area = geoProp->getGeoProp(Acoustics::FITKSEASubSysGeoProp::GeoPropType::Area);
            double size = sqrt( area / number * 4 / sqrt(3) );
            _ui->lineEdit_ElemLength->setText(QString::number(size));
        }
        _ui->lineEdit_ElemLength->blockSignals(false);
    }

    void GUIFESubSysFormSEASubSysDialog::on_lineEdit_ElemLength_2_textChanged(QString text)
    {
        double size = text.toDouble();
        if (_subSysObj == nullptr || size < 1e-15) return;
        //阻塞信号触发
        _ui->lineEdit_ElemNumber_2->blockSignals(true);
        //获取类型
        Acoustics::FITKAbstractSEASubSys::SEASubSysType type = _subSysObj->getSEASubSysType();
        Acoustics::FITKSEASubSysGeoProp* geoProp = _subSysObj->getGeoProp();
        if (type == Acoustics::FITKAbstractSEASubSys::SEASubSysType::SEACavity)
        {
            //获取体积
            double volume = geoProp->getGeoProp(Acoustics::FITKSEASubSysGeoProp::GeoPropType::Volume);
            int num = volume / (sqrt(3) * size * size * size / 24 );
            _ui->lineEdit_ElemNumber_2->setText(QString::number(num));
        }
        _ui->lineEdit_ElemNumber_2->blockSignals(false);
    }

    void GUIFESubSysFormSEASubSysDialog::on_lineEdit_ElemNumber_2_textChanged(QString text)
    {
        int number = text.toDouble();
        if (_subSysObj == nullptr || number <= 0) return;
        //阻塞信号触发
        _ui->lineEdit_ElemLength_2->blockSignals(true);
        //获取类型
        Acoustics::FITKAbstractSEASubSys::SEASubSysType type = _subSysObj->getSEASubSysType();
        Acoustics::FITKSEASubSysGeoProp* geoProp = _subSysObj->getGeoProp();
        if (type == Acoustics::FITKAbstractSEASubSys::SEASubSysType::SEACavity)
        {
            //获取体积
            double volume = geoProp->getGeoProp(Acoustics::FITKSEASubSysGeoProp::GeoPropType::Volume);
            int size = pow(volume / number * 24 / sqrt(3), 1.0 / 3);
            _ui->lineEdit_ElemLength_2->setText(QString::number(size));
        }
        _ui->lineEdit_ElemLength_2->blockSignals(false);
    }

    void GUIFESubSysFormSEASubSysDialog::on_comboBox_PickType_currentIndexChanged(int index)
    {
        //获取拾取类型
        GUI::GUIPickInfo::PickObjType pickType = GUI::GUIPickInfo::PickObjType(_ui->comboBox_PickType->currentData().toInt());
        GUI::GUIPickInfoStru pickInfo = GUI::GUIPickInfo::GetPickInfo();
        pickInfo._pickMethod = GUI::GUIPickInfo::PickMethod::PMNone;
        pickInfo._pickObjType = pickType;
        //结构-SEA板
        if (pickType == GUI::GUIPickInfo::PickObjType::POBJSEAShell)
        {
            pickInfo._pickMethod = GUI::GUIPickInfo::PickMethod::PMSingle;
            _ui->checkBox_Pid->setHidden(true);
            _ui->tabWidget->setHidden(false);
            _ui->groupBox_2->setHidden(false);
        }
        //结构-SEA梁
        else if (pickType == GUI::GUIPickInfo::PickObjType::POBJSEABeam)
        {
            pickInfo._pickMethod = GUI::GUIPickInfo::PickMethod::PMSingle;
            _ui->checkBox_Pid->setHidden(true);
            _ui->tabWidget->setHidden(false);
            _ui->groupBox_2->setHidden(true);
        }
        //腔体-SEA声腔
        else if (pickType == GUI::GUIPickInfo::PickObjType::POBJSEACavity)
        {
            pickInfo._pickMethod = GUI::GUIPickInfo::PickMethod::PMSingle;
            _ui->checkBox_Pid->setHidden(true);
            _ui->tabWidget->setHidden(false);
        }
        //结构-面网格
        else if (pickType == GUI::GUIPickInfo::PickObjType::POBJMeshCell2D)
        {
            _ui->tabWidget->setHidden(true);
            _ui->checkBox_Pid->setHidden(false);
            if (_ui->checkBox_Pid->checkState() == Qt::CheckState::Checked)
                pickInfo._pickMethod = GUI::GUIPickInfo::PickMethod::PMByMeshProp;
            else
                pickInfo._pickMethod = GUI::GUIPickInfo::PickMethod::PMIndividually;
        }
        //结构-线网格， 腔体-体网格
        else if (pickType == GUI::GUIPickInfo::PickObjType::POBJMeshCell1D || pickType == GUI::GUIPickInfo::PickObjType::POBJMeshCell3D)
        {
            pickInfo._pickMethod = GUI::GUIPickInfo::PickMethod::PMIndividually;
            _ui->tabWidget->setHidden(true);
            _ui->checkBox_Pid->setHidden(true);
        }
        //设置拾取类型
        GUI::GUIPickInfo::SetPickInfo(pickInfo);
    }

    void GUIFESubSysFormSEASubSysDialog::on_checkBox_Pid_stateChanged(int state)
    {
        //获取拾取类型
        GUI::GUIPickInfo::PickObjType pickType = GUI::GUIPickInfo::PickObjType(_ui->comboBox_PickType->currentData().toInt());
        GUI::GUIPickInfoStru pickInfo = GUI::GUIPickInfo::GetPickInfo();
        pickInfo._pickMethod = GUI::GUIPickInfo::PickMethod::PMNone;
        pickInfo._pickObjType = pickType;
        if (state == Qt::CheckState::Checked)
            pickInfo._pickMethod = GUI::GUIPickInfo::PickMethod::PMByMeshProp;
        else
            pickInfo._pickMethod = GUI::GUIPickInfo::PickMethod::PMIndividually;
        //设置拾取类型
        GUI::GUIPickInfo::SetPickInfo(pickInfo);
    }

    void GUIFESubSysFormSEASubSysDialog::on_checkBox_CoalesceNode_stateChanged(int state)
    {
        _ui->lineEdit_MergeNode->setEnabled(state);
    }

    void GUIFESubSysFormSEASubSysDialog::reject()
    {
        //清除拾取模式和高亮
        GUI::GUIPickInfo::ClearPickInfo();
        this->QDialog::reject();
    }

    void GUIFESubSysFormSEASubSysDialog::pickDataFinished()
    {
        //获取三维可视化对象管理
        GraphData::PickedDataProvider* pickProvider = GraphData::PickedDataProvider::getInstance();
        if (!pickProvider)return;
        //获取拾取数据对象
        QList<GraphData::PickedData*> pickList = pickProvider->getPickedList();
        //拾取FE数据ID
        int objID = -1;
        for (GraphData::PickedData* pickData : pickList)
        {
            if (!pickData) continue;
            objID = pickData->getPickedDataObjId();
        }
        //获取节点管理器 
        Acoustics::FITKAcousticsDiscModel *discModel = FITKAPP->getGlobalData()->getMeshData<Acoustics::FITKAcousticsDiscModel>();
        if (!discModel) return;
        //获取板的数据
        Acoustics::FITKAcousticsSEAModel* seaModel = discModel->getSEAModel();
        if (!seaModel)return;
        Acoustics::FITKAcousticsSEASubSysManager* subSysMgr = seaModel->getSEASubSysManager();
        if (!subSysMgr) return;
        _subSysObj = subSysMgr->getDataByID(objID);
        int type = 0;
        if (!_oper->argValue<int>("FESubSysType", type)) return;
        //更新尺寸
        if (type == Acoustics::FITKAbstractFESubSys::FESubSysType::FEStructure)
        {
            if (_ui->radioButton_ElemLength->isChecked())
                this->on_lineEdit_ElemLength_textChanged(_ui->lineEdit_ElemLength->text());
            else
                this->on_lineEdit_ElemNumber_textChanged(_ui->lineEdit_ElemNumber->text());
        }
        else if (type == Acoustics::FITKAbstractFESubSys::FESubSysType::FEAcoustic)
        {
            if (_ui->radioButton_ElemLength_2->isChecked())
                this->on_lineEdit_ElemLength_2_textChanged(_ui->lineEdit_ElemLength_2->text());
            else
                this->on_lineEdit_ElemNumber_2_textChanged(_ui->lineEdit_ElemNumber_2->text());
        }
    }
}
